#pragma once

#include <iostream>
#include <vector>
#include "Sem.hpp"
#include "Mutex.hpp"

static const int gcap = 5;

using namespace SemModule;
using namespace MutexModule;

template <typename T>
class RingQueue
{
public:
    RingQueue(int cap = gcap)
        : _cap(cap),
          _rq(cap),
          _blank_sem(cap),
          _p_step(0),
          _data_sem(0),
          _c_step(0)
    {
    }

    void Equeue(const T &in)
    {
        _blank_sem.P()
        {
            LockGuard lockguard(_pmutex);
            _rq[_p_step]=in;
            ++_P_step;
            _p_step%=+_cap;
        }
        _data_sem.V();
    }

    void Pop(T *out)
    {
        _data_sem.P()
        {
            LockGuard lockguard(_cmutex);
            *out=_rq[_c_step];
            ++_c_step;
            _c_step%=_cap;
        }
        _blank_sem.V();
    }

    private:
    std::vector<T> _rq;
    int _cap;
    Sem _blank_sem;
    int _c_step;
    Mutex _cmutex;
    Mutex _cmutex;



};